

This project is part of the
@thi.ng/umbrella monorepo.
About
Function collection for modular GPGPU / shader programming with @thi.ng/shader-ast.
A growing collection (currently 110+) of useful functions & higher order
constructs for GPU / shader programming, acting as optional standard
library for
@thi.ng/shader-ast
based workflows.
These functions can be imported like normal TS/JS functions and (in TS)
are fully type checked.
Some of the functions have been ported from GLSL:
- Signed Distance Field primitives and operations are based on work by
Inigo Quilezles (iq).
- Hash functions (PRNGs) by Dave Hoskins
- Noise functions by Ashima Arts / Stefan Gustavson
- Various functions from thi.ng/shadergraph, thi.ng/vectors,
thi.ng/matrices, thi.ng/color
Reference:
Status
STABLE - used in production
Related packages
Installation
yarn add @thi.ng/shader-ast-stdlib
// ES module
<script type="module" src="https://unpkg.com/@thi.ng/shader-ast-stdlib?module" crossorigin></script>
// UMD
<script src="https://unpkg.com/@thi.ng/shader-ast-stdlib/lib/index.umd.js" crossorigin></script>
Package sizes (gzipped, pre-treeshake): ESM: 5.76 KB / CJS: 6.53 KB / UMD: 6.00 KB
Dependencies
Usage examples
Several demos in this repo's
/examples
directory are using this package.
A selection:
Screenshot | Description | Live demo | Source |
---|
 | 2D canvas shader emulation | Demo | Source |
 | Evolutionary shader generation using genetic programming | Demo | Source |
 | HOF shader procedural noise function composition | Demo | Source |
 | WebGL & JS canvas2D raymarch shader cross-compilation | Demo | Source |
 | WebGL & JS canvas 2D SDF | Demo | Source |
 | WebGL & Canvas2D textured tunnel shader | Demo | Source |
 | Fork-join worker-based raymarch renderer | Demo | Source |
| Minimal multi-pass / GPGPU example | Demo | Source |
 | Shadertoy-like WebGL setup | Demo | Source |
 | WebGL screenspace ambient occlusion | Demo | Source |
API
Generated API docs
Basic Lambert shader
Below is a brief demonstration of a fully defined shader pair,
implementing basic diffuse lighting:
import { assign, defMain, vec4 } from "@thi.ng/shader-ast";
import { diffuseLighting, halfLambert, transformMVP } from "@thi.ng/shader-ast-stdlib";
import { shader } from "@thi.ng/webgl";
const gl = ...
const myShader = shader(gl, {
vs: (gl, unis, ins, outs) => [
defMain(() => [
assign(outs.vnormal, ins.normal),
assign(gl.gl_Position, transformMVP(ins.position, unis.model, unis.view, unis.proj)),
])
],
fs: (gl, unis, ins, outs) => [
defMain(() => [
assign(
outs.fragCol,
vec4(
diffuseLighting(
halfLambert(normalize(ins.vnormal), unis.lightDir),
unis.diffuseCol,
unis.lightCol,
unis.ambientCol
),
1
)
)
])
],
attribs: {
position: ["vec3", 0],
normal: ["vec3", 1]
},
varying: {
vnormal: "vec3"
},
uniforms: {
model: "mat4",
view: "mat4",
proj: "mat4",
lightDir: ["vec3", [0, 1, 0]],
lightCol: ["vec3", [1, 1, 1]],
diffuseCol: ["vec3", [0.8, 0, 0]],
ambientCol: ["vec3", [0.1, 0.1, 0.1]]
}
});
Generated vertex shader
The #define
s are auto-injected by default, but can be disabled /
customized / replaced...
#version 300 es
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp int;
precision highp float;
#else
precision mediump int;
precision mediump float;
#endif
#ifndef PI
#define PI 3.141592653589793
#endif
#ifndef TAU
#define TAU 6.283185307179586
#endif
#ifndef HALF_PI
#define HALF_PI 1.570796326794896
#endif
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
uniform vec3 lightDir;
uniform vec3 lightCol;
uniform vec3 diffuseCol;
uniform vec3 ambientCol;
layout(location=0) in vec3 position;
layout(location=1) in vec3 normal;
out vec3 vnormal;
void main() {
vnormal = normal;
gl_Position = ((proj * (view * model)) * vec4(position, 1.0));
}
Generated fragment shader
The fragColor
output variable is auto-created by
@thi.ng/webgl
if no other output vars are defined. For WebGL v1 this is defined as an
alias for gl_FragColor
...
#version 300 es
/* (omitting #define's for brevity, same as in VS) */
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
uniform vec3 lightDir;
uniform vec3 lightCol;
uniform vec3 diffuseCol;
uniform vec3 ambientCol;
in vec3 vnormal;
layout(location=0) out vec4 fragColor;
void main() {
fragColor = vec4((((lightCol * ((dot(normalize(vnormal), lightDir) * 0.5) + 0.5)) * diffuseCol) + ambientCol), 1.0);
}
Using higher order functions
Several of the functions included here are defined as higher-order
functions, providing powerful functional compositional features not
usually seen in shader code and not easily achievable via the usual
string templating approach used by most other GLSL libraries.
For example, the
additive()
HOF takes a single-arg scalar function and a number of octaves. It
returns a new function which computes the summed value of fn
over the
given number octaves, with a user defined phase shift & decay factor
(per octave). This can be used for additive wave synthesis, multi-octave
noise or any other similar use cases...
Due to the way user defined AST functions keep track of their own call
graph, the anonymous function returned by additive
does not need to be
pre-declared in any way and also ensures all of its own function
dependencies are resolved and emitted in the correct topological order
during later code generation.
Below is the main shader code of the Simplex noise
example.
import { add, defn, float, ret, sym, vec2, vec3, vec4 } from "@thi.ng/shader-ast";
import { additive, aspectCorrectedUV, fit1101, snoise2 } from "@thi.ng/shader-ast-stdlib";
const mainImage = defn(
"vec4",
"mainImage",
["vec2", "vec2", "float"],
(frag, res, time) => {
let uv;
let noise;
return [
uv = sym(aspectCorrectedUV(frag, res)),
noise = sym(
additive("vec2", snoise2, 4)(add(uv, time), vec2(2), float(0.5))
),
ret(vec4(vec3(fit1101(noise)), 1))
];
}
);
Run the above-linked example and view the console to see the full
generated shader code. Also check out the raymarching demo which uses
several other HOFs from this library to drastically simplify user code.
API
TODO. For now, please see doc strings in source for details...
Color
/src/color
toLinear
toSRGB
luminanceRGB
Porter-Duff alpha blending
Use the porterDuff
higher order function to define new blend modes.
See
@thi.ng/porter-duff
for reference.
12 standard PD operators for vec4
RGBA colors:
blendSrcOver
blendDestOver
blendSrcIn
blendDestIn
blendSrcOut
blendDestOut
blendSrcAtop
blendDestAtop
blendXor
blendPlus
Fog
/src/fog
Lighting
/src/light
lambert
halfLambert
diffuseLighting
trilight
Math
/src/math
additive
cartesian2
/ cartesian3
clamp01
/ clamp11
cross2
/ crossC2
distChebyshev2
/ distChebyshev3
/ distChebyshev4
distManhattan2
/ distManhattan3
/ distManhattan4
fit01
/ fit11
/ fit1101
/ fit0111
magSq2
/ magSq3
/ magSq4
maxComp2
/ maxComp3
/ maxComp4
minComp2
/ minComp3
/ minComp4
perpendicularCCW
/ perpendicularCW
orthogonal3
polar2
/ polar3
sincos
/ cossin
Matrix operations
/src/matrix
lookat
transformMVP
surfaceNormal
rotation2
rotationX3
/ rotationY3
/ rotationZ3
rotationX4
/ rotationY4
/ rotationZ4
Noise / randomness
/src/noise
hash2
/ hash3
hash11
/ hash12
/ hash13
hash21
/ hash22
/ hash23
hash31
/ hash32
/ hash33
hash41
/ hash42
/ hash43
/ hash44
permute
/ permute3
/ permute4
snoise2
voronoise2
worley2
/ worleyDist
/ worleyDistManhattan
Raymarching
/src/raymarch
raymarchAO
raymarchDir
raymarchNormal
raymarchScene
rayPointAt
Screen coordinates
/src/screen
Signed Distance Fields
/src/sdf
sdfAnnular
sdfBox2
sdfBox3
sdfCircle
sdfCylinder
sdfIntersect
sdfLine2
sdfLine3
sdfPlane2
sdfPlane3
sdfRepeat2
sdfRepeat3
sdfRound
sdfSmoothIntersect
sdfSmoothSubtract
sdfSmoothUnion
sdfSphere
sdfTorus
sdfTriangle2
sdfUnion
Texture lookups
/src/tex
indexToCoord
/ coordToIndex
indexToUV
/ uvToIndex
readIndex1
/ readIndex2
/ readIndex3
/ readIndex4
Authors
Karsten Schmidt
License
© 2019 - 2020 Karsten Schmidt // Apache Software License 2.0